home *** CD-ROM | disk | FTP | other *** search
- /* fsinfo.c -- return info about mounted filesystems
- Copyright (C) 1991 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-
- #include <stdio.h>
- #include <sys/types.h>
- #include <errno.h>
- #include "fsinfo.h"
-
- #ifdef STDC_HEADERS
- #include <stdlib.h>
- #else
- extern int errno;
- void exit ();
- void free ();
- #endif
- #if defined(USG) || defined(STDC_HEADERS)
- #include <string.h>
- #else
- #include <strings.h>
- #endif
-
- int statfs ();
-
- int xatoi ();
- char *strstr ();
- char *xmalloc ();
- char *xrealloc ();
- char *xstrdup ();
- void error ();
-
- #ifdef FS_MNTENT
- #include <sys/vfs.h>
- #include <mntent.h>
- #if !defined(MOUNTED) && defined(MNT_MNTTAB) /* HP-UX. */
- #define MOUNTED MNT_MNTTAB
- #endif
- #endif /* FS_MNTENT */
-
- #ifdef FS_GETMNT
- #include <sys/param.h>
- #include <sys/mount.h>
- #include <sys/fs_types.h>
- int getmnt ();
- #endif
-
- #ifdef FS_USG_STATFS
- #include <mnttab.h>
- #include <sys/statfs.h>
- #include <sys/fstyp.h>
- #endif
-
- #ifdef FS_STATVFS
- #include <sys/statvfs.h>
- #include <sys/mnttab.h>
- #endif
-
- #ifdef FS_STATFS
- #include <sys/mount.h>
-
- char *
- fstype_to_string (t)
- short t;
- {
- switch (t)
- {
- case MOUNT_UFS:
- return "ufs";
- case MOUNT_NFS:
- return "nfs";
- case MOUNT_PC:
- return "pc";
- #ifdef MOUNT_MFS
- case MOUNT_MFS:
- return "mfs";
- #endif
- #ifdef MOUNT_LO
- case MOUNT_LO:
- return "lo";
- #endif
- #ifdef MOUNT_TFS
- case MOUNT_TFS:
- return "tfs";
- #endif
- #ifdef MOUNT_TMP
- case MOUNT_TMP:
- return "tmp";
- #endif
- default:
- return "?";
- }
- }
- #endif
-
- #ifdef __MINT__
- #include <dirent.h>
- #include <stat.h>
- #include <osbind.h>
-
- /* keep the linker happy */
- void sync() { return; };
- #endif
-
- /* Return a list of the currently mounted filesystems, or NULL on error.
- Add each entry to the tail of the list so that they stay in order.
- If NEED_FS_TYPE is nonzero, make sure the filesystem type fields in
- the returned list are valid. */
-
- struct mount_entry *
- read_filesystem_list (need_fs_type)
- int need_fs_type;
- {
- struct mount_entry *mount_list;
- struct mount_entry *me;
- struct mount_entry *mtail;
-
- /* Start the list off with a dummy entry. */
- me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
- me->me_next = NULL;
- mount_list = mtail = me;
-
- #ifdef FS_MNTENT /* 4.3BSD, SunOS, HP-UX */
- {
- struct mntent *mnt;
- char *table = MOUNTED; /* /etc/mtab, usually. */
- FILE *fp;
- char *devopt;
-
- fp = setmntent (table, "r");
- if (fp == NULL)
- return NULL;
-
- while ((mnt = getmntent (fp)))
- {
- me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
- me->me_devname = xstrdup (mnt->mnt_fsname);
- me->me_mountdir = xstrdup (mnt->mnt_dir);
- me->me_type = xstrdup (mnt->mnt_type);
- devopt = strstr (mnt->mnt_opts, "dev=");
- if (devopt)
- {
- if (devopt[4] == '0' && (devopt[5] == 'x' || devopt[5] == 'X'))
- me->me_dev = xatoi (devopt + 6);
- else
- me->me_dev = xatoi (devopt + 4);
- }
- else
- me->me_dev = -1; /* Magic; means not known yet. */
- me->me_next = NULL;
-
- /* Add to the linked list. */
- mtail->me_next = me;
- mtail = me;
- }
-
- if (endmntent (fp) == 0)
- return NULL;
- }
- #endif /* FS_MNTENT */
-
- #ifdef FS_GETMNT /* Ultrix */
- {
- int offset = 0;
- int val;
- struct fs_data fsd;
-
- while ((val = getmnt (&offset, &fsd, sizeof (fsd), NOSTAT_MANY,
- (char *) 0)) > 0)
- {
- me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
- me->me_devname = xstrdup (fsd.fd_req.devname);
- me->me_mountdir = xstrdup (fsd.fd_req.path);
- me->me_type = gt_names[fsd.fd_req.fstype];
- me->me_dev = fsd.fd_req.dev;
- me->me_next = NULL;
-
- /* Add to the linked list. */
- mtail->me_next = me;
- mtail = me;
- }
- if (val < 0)
- return NULL;
- }
- #endif /* FS_GETMNT */
-
- #ifdef FS_USG_STATFS /* SVR3.2 */
- {
- struct mnttab mnt;
- char *table = "/etc/mnttab";
- FILE *fp;
-
- fp = fopen (table, "r");
- if (fp == NULL)
- return NULL;
-
- while (fread (&mnt, sizeof mnt, 1, fp) > 0)
- {
- me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
- me->me_devname = xstrdup (mnt.mt_dev);
- me->me_mountdir = xstrdup (mnt.mt_filsys);
- me->me_dev = -1; /* Magic; means not known yet. */
- me->me_type = "";
- if (need_fs_type)
- {
- struct statfs fsd;
- char typebuf[FSTYPSZ];
-
- if (statfs (me->me_mountdir, &fsd, sizeof fsd, 0) != -1
- && sysfs (GETFSTYP, fsd.f_fstyp, typebuf) != -1)
- me->me_type = xstrdup (typebuf);
- }
- me->me_next = NULL;
-
- /* Add to the linked list. */
- mtail->me_next = me;
- mtail = me;
- }
-
- if (fclose (fp) == EOF)
- return NULL;
- }
- #endif /* FS_USG_STATFS */
-
- #ifdef FS_STATVFS /* SVR4 */
- {
- struct mnttab mnt;
- char *table = MNTTAB;
- FILE *fp;
- int ret;
-
- fp = fopen (table, "r");
- if (fp == NULL)
- return NULL;
-
- while ((ret = getmntent (fp, &mnt)) == 0)
- {
- me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
- me->me_devname = xstrdup (mnt.mnt_special);
- me->me_mountdir = xstrdup (mnt.mnt_mountp);
- me->me_type = xstrdup (mnt.mnt_fstype);
- me->me_dev = -1; /* Magic; means not known yet. */
- me->me_next = NULL;
-
- /* Add to the linked list. */
- mtail->me_next = me;
- mtail = me;
- }
-
- if (ret > 0)
- return NULL;
- if (fclose (fp) == EOF)
- return NULL;
- }
- #endif
-
- #ifdef FS_STATFS /* 4.4BSD */
- {
- struct statfs *fsp;
- int entries;
-
- entries = getmntinfo (&fsp, MNT_NOWAIT);
- if (entries < 0)
- return NULL;
- while (entries-- > 0)
- {
- me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
- me->me_devname = xstrdup (fsp->f_mntfromname);
- me->me_mountdir = xstrdup (fsp->f_mntonname);
- me->me_type = fstype_to_string (fsp->f_type);
- me->me_dev = -1; /* Magic; means not known yet. */
- me->me_next = NULL;
-
- /* Add to the linked list. */
- mtail->me_next = me;
- mtail = me;
- fsp++;
- }
- }
- #endif /* FS_STATFS */
-
- #ifdef __MINT__ /* MiNT on Atari ST */
- {
- static char ubuf[128] = "u:/";
- DIR *udrv;
- struct dirent *next;
- struct stat statbuf;
- long drvmap, ssp;
- int i;
- int offset;
- struct mount_entry *him;
-
- offset = (Dgetdrv() == 'U'-'A') ? 2 : 0;
- ssp = Super(0L);
- drvmap = *((long *)0x4c2); /* get which drives are attached */
- if ((*(short *)0x4a6) != 2)
- drvmap &= ~2; /* drive B: isn't really there */
- Super(ssp);
-
- for (i = 0; i < 32; i++)
- {
- if (drvmap & (1L << i))
- {
- me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
- me->me_devname = xstrdup("a:");
- me->me_devname[0] = 'a'+i;
- me->me_mountdir = xstrdup(ubuf);
- me->me_mountdir[0] = me->me_devname[0];
- me->me_dev = i;
- me->me_next = NULL;
- me->me_type = xstrdup( (i < 16) ? "tos" : "pseudo" );
- mtail->me_next = me;
- mtail = me;
- }
- }
- udrv = opendir(ubuf);
- if (udrv)
- {
- while (next = readdir(udrv))
- {
- strcpy(ubuf+3, next->d_name);
- lstat(ubuf, &statbuf);
- if ( (statbuf.st_mode & S_IFMT) == S_IFDIR )
- for (him = mount_list->me_next; him; him = him->me_next)
- {
- if (him->me_devname[0] - 'a' == statbuf.st_dev)
- {
- free(him->me_mountdir);
- him->me_mountdir = xstrdup(ubuf+offset);
- break;
- }
- }
- }
- }
- }
- #endif /* __MINT__ */
-
- /* Free the dummy head. */
- me = mount_list;
- mount_list = mount_list->me_next;
- free (me);
- return mount_list;
- }
-
- /* Fill in the fields of FSP with information about space usage on
- the filesystem on which PATH is a node.
- Return 0 if successful, -1 if not. */
-
- int
- get_fs_usage (path, fsp)
- char *path;
- struct fs_usage *fsp;
- {
- #ifdef FS_MNTENT
- struct statfs fsd;
-
- if (statfs (path, &fsd) != 0)
- return -1;
- fsp->fsu_blocks = fsd.f_blocks;
- fsp->fsu_bfree = fsd.f_bfree;
- fsp->fsu_bavail = fsd.f_bavail;
- fsp->fsu_files = fsd.f_files;
- fsp->fsu_ffree = fsd.f_ffree;
- #endif /* FS_MNTENT */
-
- #ifdef FS_USG_STATFS
- #define f_bavail f_bfree
- struct statfs fsd;
-
- if (statfs (path, &fsd, sizeof fsd, 0) < 0)
- return -1;
- fsp->fsu_blocks = (fsd.f_blocks + 1) / 2;
- fsp->fsu_bfree = (fsd.f_bfree + 1) / 2;
- fsp->fsu_bavail = (fsd.f_bavail + 1) / 2;
- fsp->fsu_files = fsd.f_files;
- fsp->fsu_ffree = fsd.f_ffree;
- #endif
-
- #ifdef FS_STATVFS
- struct statvfs fsd;
-
- if (statvfs (path, &fsd) < 0)
- return -1;
- fsp->fsu_blocks = (fsd.f_blocks + 1) / (1024 / fsd.f_frsize);
- fsp->fsu_bfree = (fsd.f_bfree + 1) / (1024 / fsd.f_frsize);
- fsp->fsu_bavail = (fsd.f_bavail + 1) / (1024 / fsd.f_frsize);
- fsp->fsu_files = fsd.f_files;
- fsp->fsu_ffree = fsd.f_ffree;
- #endif
-
- #ifdef FS_STATFS
- struct statfs fsd;
-
- if (statfs (path, &fsd) < 0)
- return -1;
- fsp->fsu_blocks = (fsd.f_blocks + 1) / (1024 / fsd.f_fsize);
- fsp->fsu_bfree = (fsd.f_bfree + 1) / (1024 / fsd.f_fsize);
- fsp->fsu_bavail = (fsd.f_bavail + 1) / (1024 / fsd.f_fsize);
- fsp->fsu_files = fsd.f_files;
- fsp->fsu_ffree = fsd.f_ffree;
- #endif
-
- #ifdef FS_GETMNT
- struct fs_data fsd;
-
- if (statfs (path, &fsd) != 1)
- return -1;
- fsp->fsu_blocks = fsd.fd_req.btot;
- fsp->fsu_bfree = fsd.fd_req.bfree;
- fsp->fsu_bavail = fsd.fd_req.bfreen;
- fsp->fsu_files = fsd.fd_req.gtot;
- fsp->fsu_ffree = fsd.fd_req.gfree;
- #endif /* FS_GETMNT */
-
- #ifdef __MINT__
- extern int errno;
- struct stat sbuf;
- long dfree[4], r, clsiz;
-
- if (stat(path, &sbuf)) return -1;
- r = Dfree(dfree, sbuf.st_dev+1);
- if (r) {
- errno = -r;
- return -1;
- }
- clsiz = dfree[2] * dfree[3];
- fsp->fsu_files = dfree[1];
- fsp->fsu_ffree = dfree[0];
- fsp->fsu_blocks = ((dfree[1] * clsiz) + 1) / 1024;
- fsp->fsu_bfree = fsp->fsu_bavail = ((dfree[0] * clsiz) + 1) / 1024;
- #endif /* __MINT__ */
-
- return 0;
- }
-
- /* Return the value of the hexadecimal number represented by CP.
- No prefix (like '0x') or suffix (like 'h') is expected to be
- part of CP. */
-
- int
- xatoi (cp)
- char *cp;
- {
- int val;
-
- val = 0;
- while (*cp)
- {
- if (*cp >= 'a' && *cp <= 'f')
- val = val * 16 + *cp - 'a' + 10;
- else if (*cp >= 'A' && *cp <= 'F')
- val = val * 16 + *cp - 'A' + 10;
- else if (*cp >= '0' && *cp <= '9')
- val = val * 16 + *cp - '0';
- else
- break;
- cp++;
- }
- return val;
- }
-